package com.bsoft.gol.hcb.dao.prescriptionCirculation;

import com.bsoft.gol.hcb.utils.CommonUtils;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.spring.boot.annotation.SsdevDao;
import ctd.util.annotation.RpcService;
import ctd.util.converter.ConversionUtils;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import pcn.bean.consultation.ExpressOrderQo;
import pcn.bean.consultation.ExpressOrderVo;
import pcn.bean.consultation.QueryDrugOrderListQo;
import pcn.prescribe.OdsPrescriptionOrder;
import pcn.vo.consultation.QueryDrugOrderListVo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Author zhusm@bsoft.com
 * @Description 订单表Dao
 * @Date 2019/12/26
 */
@SsdevDao(serviceId = "odsPrescriptionOrderDAOService")
public abstract class OdsPrescriptionOrderDAO extends HibernateSupportDelegateDAO<OdsPrescriptionOrder> {
    public OdsPrescriptionOrderDAO() {
        this.setKeyField("orderId");
    }

    @RpcService
    @DAOMethod(sql = "from OdsPrescriptionOrder where payStatus='1'  and createTime>=:beginDate and createTime<:endDate ")
    public abstract List<OdsPrescriptionOrder> queryOdsPrescriptionOrdersByCreateTime(@DAOParam("beginDate") Date beginDate, @DAOParam("endDate") Date endDate);

    @RpcService
    @DAOMethod(sql = "from OdsPrescriptionOrder where userId =:userId ")
    public abstract List<OdsPrescriptionOrder> queryByUserId(@DAOParam("userId") String userId,@DAOParam(pageStart = true) int start, @DAOParam(pageLimit = true) int limit);

    @DAOMethod(sql = "select distinct a.orderId  from OdsPrescriptionOrder a,OdsOrderToPrescription b where a.orderId =b.orderId and a.userId=:userId and b.feeType in:feeTypeIdList ")
    public abstract List<String> queryOrderIdList(@DAOParam("userId")String userId, @DAOParam("feeTypeIdList") List<String> feeTypeIdList);

    @DAOMethod(sql = "select distinct a.orderId  from OdsPrescriptionOrder a,OdsOrderToPrescription b where a.orderId =b.orderId and a.userId=:userId and b.feeType in:feeTypeIdList and a.orderId in:orderIdList")
    public abstract List<String> queryPreOrderIdList(@DAOParam("userId")String userId, @DAOParam("feeTypeIdList") List<String> feeTypeIdList,@DAOParam("orderIdList") List<String> orderIdList);

    @DAOMethod(sql = "from OdsPrescriptionOrder where tradeNo =:tradeNo")
    public abstract OdsPrescriptionOrder getOdsPrescriptionOrder(@DAOParam("tradeNo")String tradeNo);

    @DAOMethod(sql = "update OdsPrescriptionOrder set payStatus='3' where orderId in:orderIdList")
    public abstract void updateOdsPrescriptionOrderPayStatus(@DAOParam("orderIdList")List<String> orderIdList);

    @DAOMethod(sql = "from OdsPrescriptionOrder where payStatus ='0' and payExpireTime<=:date and payWay='1'")
    public abstract List<OdsPrescriptionOrder> queryOdsPrescriptionOrdersByPayExpireTime(@DAOParam("date") Date date);

    @DAOMethod(sql = " from OdsPrescriptionOrder where orgId=:orgId and mpiId=:mpiId and payStatus = 1  order by createTime asc")
    public abstract List<OdsPrescriptionOrder> findAlreadyCloudPayList(@DAOParam("orgId")String orgId,@DAOParam("mpiId")String mpiId);

    @DAOMethod(sql = " from OdsPrescriptionOrder where orgId=:orgId and mpiId=:mpiId and payStatus =:payStatus order by createTime desc")
    public abstract List<OdsPrescriptionOrder> findAlreadyCloudPayListByPayStatus(@DAOParam("orgId")String orgId,@DAOParam("mpiId")String mpiId,@DAOParam("payStatus")String payStatus);

    @DAOMethod(sql = " from OdsPrescriptionOrder where orgId=:orgId and mpiId=:mpiId and payStatus =:payStatus order and invoiceNumber in:invoiceNumberList by createTime desc")
    public abstract List<OdsPrescriptionOrder> findAlreadyCloudPayListByInvoiceNumberList(@DAOParam("orgId") String orgId, @DAOParam("mpiId") String mpiId, @DAOParam("payStatus") String payStatus, @DAOParam("invoiceNumberList") List<String> invoiceNumberList);

    @DAOMethod(sql = " from OdsPrescriptionOrder where orgId=:orgId and mpiId=:mpiId and payStatus = 1  and payTime >=:beginPayTime and payTime <:endPayTime order by createTime asc")
    public abstract List<OdsPrescriptionOrder> findAlreadyCloudPayListByPayTime(@DAOParam("orgId") String orgId, @DAOParam("mpiId") String mpiId, @DAOParam("beginPayTime") Date beginPayTime, @DAOParam("endPayTime") Date endPayTime);

    @DAOMethod(sql = " from OdsPrescriptionOrder where platform_order_id=:orderNo ")
    public abstract OdsPrescriptionOrder getOrderByOrderNo(@DAOParam("orderNo")String orderNo);

    @RpcService
    public void updateOdsPrescriptionOrder(OdsPrescriptionOrder odsPrescriptionOrder){
        this.update(odsPrescriptionOrder);
    }

    @RpcService
    public void saveOdsPrescriptionOrder(OdsPrescriptionOrder odsPrescriptionOrder){
        this.save(odsPrescriptionOrder);
    }

    public List<ExpressOrderVo> findOdsPrescriptionOrders(final ExpressOrderQo request){
        HibernateStatelessResultAction<List<ExpressOrderVo>> action = new AbstractHibernateStatelessResultAction<List<ExpressOrderVo>>() {
            @Override
            public void execute(StatelessSession ss) {
                StringBuilder sql = new StringBuilder("select DISTINCT " +
                        "       opo.order_id        as orderId," +
                        "       opo.invoice_number   as invoiceNumber," +
                        "       opo.create_time      as orderTime," +
                        "       opo.person_name        as reciverName," +
                        "       opo.total_fee        as totalFee," +
                        "       oei.take_way         as takeWay," +
                        "       opo.pay_status        as payStatus," + //支付状态
                        "       opo.pay_way        as payWay," +//支付方式
                        "       opo.order_status      as orderStatus," +
                        "       opo.patient_medical_card_number as outpatientNumber" +
                        "       from ods_prescription_order opo" +
                        "       left join ods_order_to_prescription ootp on opo.order_id = ootp.order_id" +
                        "       left join ods_express_info oei on oei.order_id = opo.order_id" +
                        "       left join express_order eo on eo.order_id = opo.order_id" +
                        "       left join express_order_detail eod on eod.express_id = eo.express_id" +
                        "       where ootp.fee_type not in ('4','5') and ((opo.pay_way  = 0 and opo.pay_status!=3) or opo.pay_status = 1 ) ");
                if (CommonUtils.isNotEmpty(request.getInvoiceNumber())){
                    sql.append("and opo.invoice_number like :invoiceNumber ");
                }
                if (CommonUtils.isNotEmpty(request.getBusinessType())){
                    sql.append("and ootp.consult_type=:businessType ");
                }
                if (CommonUtils.isNotEmpty(request.getReciverName())){
                    sql.append("and opo.person_name like :personName ");
                }
                if (CommonUtils.isNotEmpty(request.getOutpatientNumber())){
                    sql.append("and opo.patient_medical_card_number like :patientMedicalCardNumber ");
                }
                if (CommonUtils.isNotEmpty(request.getStatus())){
                    sql.append("and opo.order_status=:status ");
                }
                if (CommonUtils.isNotEmpty(request.getExpressCode())) {
                    sql.append("and eod.express_code=:expressCode ");
                }
                if (CommonUtils.isNotEmpty(request.getBeginTime())) {
                    sql.append("and opo.create_time between :beginTime and :endTime ");
                }
                sql.append(" group by opo.order_id, opo.invoice_number, opo.create_time,opo.person_name, opo.total_fee, oei.take_way, opo.pay_status, opo.pay_way, opo.order_status order by opo.create_time desc ");
                Query query = ss.createSQLQuery(sql.toString());
                if (CommonUtils.isNotEmpty(request.getInvoiceNumber())) {
                    query.setParameter("invoiceNumber", "%" + request.getInvoiceNumber() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getBusinessType())) {
                    query.setParameter("businessType", request.getBusinessType());
                }
                if (CommonUtils.isNotEmpty(request.getReciverName())) {
                    query.setParameter("personName", "%" + request.getReciverName() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getOutpatientNumber())) {
                    query.setParameter("patientMedicalCardNumber", request.getOutpatientNumber() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getStatus())) {
                    query.setParameter("status", request.getStatus());
                }

                if (CommonUtils.isNotEmpty(request.getExpressCode())) {
                    query.setParameter("expressCode", request.getExpressCode());
                }

                if (CommonUtils.isNotEmpty(request.getBeginTime())) {
                    query.setParameter("beginTime", request.getBeginTime() + " 00:00:00");
                    query.setParameter("endTime",request.getEndTime()+" 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                int first = request.getPageNo() > 0 ? (request.getPageNo() - 1) * request.getPageSize() : 0;
                query.setFirstResult(first);
                query.setMaxResults(request.getPageSize());
                List<Map> dbList = query.list();
                if (CommonUtils.isEmpty(dbList)) {
                    return;
                }
                List<ExpressOrderVo> signApplies = new ArrayList<>();
                for (Map map : dbList) {
                    signApplies.add(ConversionUtils.convert(map, ExpressOrderVo.class));
                }
                setResult(signApplies);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public Long getOdsPrescriptionOrdersCount(final ExpressOrderQo request){
        HibernateStatelessResultAction<Long> action = new AbstractHibernateStatelessResultAction<Long>() {
            @Override
            public void execute(StatelessSession ss) {
                StringBuilder sql = new StringBuilder();
                sql.append(" select count(1) countValue from ( ");
                sql.append("select DISTINCT " +
                        "       opo.order_id        as orderId,\n" +
                        "       opo.invoice_number   as invoiceNumber,\n" +
                        "       opo.create_time      as orderTime,\n" +
                        "       opo.person_name        as reciverName,\n" +
                        "       opo.total_fee        as totalFee,\n" +
                        "       oei.take_way         as takeWay,\n" +
                        "       opo.pay_status        as payStatus,\n" + //支付状态
                        "       opo.pay_way        as payWay,\n" +//支付方式
                        "       opo.order_status      as orderStatus \n" +
                        "       from ods_prescription_order opo\n" +
                        "       left join ods_order_to_prescription ootp on opo.order_id = ootp.order_id\n" +
                        "       left join ods_express_info oei on oei.order_id = opo.order_id\n" +
                        "       where 1=1  and (opo.pay_way  = 0 or opo.pay_status = 1 ) ");
                if (CommonUtils.isNotEmpty(request.getInvoiceNumber())){
                    sql.append("and opo.invoice_number like :invoiceNumber ");
                }
                if (CommonUtils.isNotEmpty(request.getBusinessType())){
                    sql.append("and ootp.consult_type=:businessType ");
                }
                if (CommonUtils.isNotEmpty(request.getReciverName())){
                    sql.append("and opo.person_name like :personName ");
                }
                if (CommonUtils.isNotEmpty(request.getOutpatientNumber())){
                    sql.append("and opo.patient_medical_card_number like :patientMedicalCardNumber ");
                }
                if (CommonUtils.isNotEmpty(request.getStatus())){
                    sql.append("and opo.order_status=:status ");
                }
                if (CommonUtils.isNotEmpty(request.getBeginTime())) {
                    sql.append("and opo.create_time between :beginTime and :endTime ");
                }
                sql.append(" group by opo.order_id, opo.invoice_number, opo.create_time,opo.person_name, opo.total_fee, oei.take_way, opo.pay_status, opo.pay_way, opo.order_status  order by opo.create_time desc ");

                sql.append(" ) a ");

                Query query = ss.createSQLQuery(sql.toString());
                if (CommonUtils.isNotEmpty(request.getInvoiceNumber())) {
                    query.setParameter("invoiceNumber", "%" + request.getInvoiceNumber() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getBusinessType())) {
                    query.setParameter("businessType", request.getBusinessType());
                }
                if (CommonUtils.isNotEmpty(request.getReciverName())) {
                    query.setParameter("personName", "%" + request.getReciverName() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getOutpatientNumber())) {
                    query.setParameter("patientMedicalCardNumber", request.getOutpatientNumber() + "%");
                }
                if (CommonUtils.isNotEmpty(request.getStatus())) {
                    query.setParameter("status", request.getStatus());
                }

                if (CommonUtils.isNotEmpty(request.getBeginTime())) {
                    query.setParameter("beginTime", request.getBeginTime() + " 00:00:00");
                    query.setParameter("endTime", request.getEndTime() + " 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);

                List<Map> dbList = query.list();

                if(CommonUtils.isNotEmpty(dbList)){
                    setResult(Long.valueOf(String.valueOf(dbList.get(0).get("countValue"))));
                }else {
                    setResult(0L);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 订单记录
     * @param qo
     * @return
     */
    public List<QueryDrugOrderListVo> findOrderList(final QueryDrugOrderListQo qo){
        HibernateStatelessResultAction<List<QueryDrugOrderListVo>> action = new AbstractHibernateStatelessResultAction<List<QueryDrugOrderListVo>>() {
            @Override
            public void execute(StatelessSession ss) {
                StringBuilder sql = new StringBuilder("");
                sql.append("select DISTINCT op.order_id AS orderId,oe.transfer_type transferType,op.source sourceType,exo.receipt_expire_time receiptExpireTime,exo.confirm_receipt_time receiptTime,op.pay_way AS payWay,op.trade_no as tradeNo,op.org_id AS orgId,op.create_time AS createTime,op.pay_expire_time AS payExpireTime,op.total_fee AS totalFee,op.delete_flag AS deleteFlag,op.pay_status AS payStatus,op.pay_way as payType,op.order_status AS orderStatus,oe.take_way AS takeWay,");
                sql.append(" oe.reciver_name as reciverName,oe.telephone as reciverPhone, oe.reciver_province as reciverProvince,oe.reciver_city as reciverCity,oe.reciver_district as reciverDistrict,oe.reciver_street as reciverStreet,oe.address,op.pay_time as payTime,op.operate_platform_store_id operatePlatformStoreId,op.platform_order_id platformOrderId,operate_platform_store_name operatePlatformStoreName,take_drug_code takeDrugCode");
                sql.append(" from ods_prescription_order op  " +
                        " LEFT JOIN ods_express_info oe ON oe.order_id = op.order_id  ");
                sql.append(" left join express_order exo on exo.order_id=op.order_id  ");
                sql.append(" where 1=1 and op.delete_flag='0' ");
                if(CommonUtils.isNotEmpty(qo.getConsultId())){
                    sql.append(" and op.order_id = :orderId");
                }

                sql.append(" and op.user_id = :userId ");

                if("1".equals(qo.getStatus())){
                    sql.append(" and op.pay_status= '0' and  op.pay_expire_time>now() ");
                }else if("2".equals(qo.getStatus())){
                    sql.append(" and op.order_status= '1' ");
                }else if("3".equals(qo.getStatus())){
                    sql.append(" and op.order_status= '2' ");
                }else if("4".equals(qo.getStatus())){
                    sql.append(" and op.pay_status in ( '2','3') ");
                }

                if (CommonUtils.isNotEmpty(qo.getMpiId())) {
                    sql.append(" and op.mpi_id=:mpiId ");
                }
                if (CommonUtils.isNotEmpty(qo.getOutpatientType())) {
                    sql.append(" and op.source=:source ");
                }
                sql.append(" order by op.create_time desc");
                Query query = ss.createSQLQuery(sql.toString());
                if (CommonUtils.isNotEmpty(qo.getConsultId())) {
                    query.setParameter("orderId", qo.getConsultId());
                }
                query.setParameter("userId", qo.getUserId());

                if (CommonUtils.isNotEmpty(qo.getMpiId())) {
                    query.setParameter("mpiId", qo.getMpiId());
                }
                if (CommonUtils.isNotEmpty(qo.getOutpatientType())) {
                    query.setParameter("source", qo.getOutpatientType());
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);

                int first = qo.getPageNo() > 0 ? (qo.getPageNo() - 1) * qo.getPageSize() : 0;
                query.setFirstResult(first);
                query.setMaxResults(qo.getPageSize());
                List<Map> dbList = query.list();
                if (CommonUtils.isEmpty(dbList)){
                    setResult(null);
                }else {
                    List<QueryDrugOrderListVo> signApplies = new ArrayList<>();
                    for (Map map : dbList) {
                        signApplies.add(ConversionUtils.convert(map, QueryDrugOrderListVo.class));
                    }
                    setResult(signApplies);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

//    /**
//     * 药品明细
//     * @param orderId
//     * @return
//     */
//    public List<PrescriptionDrugVo> findPrescriptionDrugList(final String orderId){
//        HibernateStatelessResultAction<List<PrescriptionDrugVo>> action = new AbstractHibernateStatelessResultAction<List<PrescriptionDrugVo>>() {
//            @Override
//            public void execute(StatelessSession ss) {
//                StringBuilder sql = new StringBuilder("");
//                sql.append(" select opd.prescription_drug_id as prescriptionDrugId,opd.trade_name as tradeName,opd.specifications,opd.price,opd.quantity from ods_prescription_drug opd where opd.prescription_info_id in ((select oot.fee_code from ods_order_to_prescription oot where  ");
//                sql.append(" oot.order_id = '"+orderId+"' and oot.fee_type=1))");
//                Query query = ss.createSQLQuery(sql.toString());
//                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
//                List<Map> dbList = query.list();
//                if (dbList.size() == 0) return;
//                List<PrescriptionDrugVo> prescriptionDrugVos = new ArrayList<>();
//                for (Map map : dbList) {
//                    prescriptionDrugVos.add(ConversionUtils.convert(map, PrescriptionDrugVo.class));
//                }
//                setResult(prescriptionDrugVos);
//            }
//        };
//        HibernateSessionTemplate.instance().execute(action);
//        return action.getResult();
//    }
}
